
#include <LiquidCrystal.h>
#include <Time.h>     // Date & Time

#include "debug.h"
#include "lcd.h"

#if 0
//
// Use this for now to sync time
//
#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by Unix time_t as ten ASCII digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 

// T1262347200  //noon Jan 1 2010
#endif // 0

//
// LCD and Keypad shield: backlight with current limiting, brightness 
// and on/off controllable by D3, can be moved to D2, D10, A1, A2, A3, 
// A4 or A5 for easy project pin compatibility.
//
// Initialize the LCD: command on bottom of board-plate
//
// LiquidCrystal(rs, rw, enable, d4, d5, d6, d7) 
//
//   rs: the number of the Arduino pin that is connected to the RS pin 
//       on the LCD 
//   rw: the number of the Arduino pin that is connected to the RW pin 
//       on the LCD (optional) - not used by this code
//   enable: the number of the Arduino pin that is connected to the 
//           enable pin on the LCD 
//   d0, d1, d2, d3, d4, d5, d6, d7: the numbers of the Arduino pins 
//       that are connected to the corresponding data pins on the LCD. 
//       d0, d1, d2, and d3 are optional; if omitted, the LCD will be 
//       controlled using only the four data lines (d4, d5, d6, d7). 
//
static LiquidCrystal lcd(8,9,4,5,6,7);

//
// Ethernet uses pins: D10 (select), D11, D12, D13
//

//
// Re-routing pins to have LCD and WiFi and SD at same time:
//  http://arduino.stackexchange.com/questions/1244/arduinounolcdkeypadarduinowifi-pins-problems

//
// Rerouting pin 7 (you need to do this! see above):
//
//  Bend pin 7 on the LCD shield and the WiFi shield outward so it doesn't 
//  make contact with the header.
//
//  Use LiquidCrystal lcd(8,9,3,5,6,2); if you're rerouting pin 4, or 
//      LiquidCrystal lcd(8,9,4,5,6,2); in your code if you're not rerouting
//
//  Attach a jumper between the pin 7 on the header of the WiFi shield and 
//  the pin 7 on the Arduino Uno
//
//  Attach a jumper between the pin 2 of the WiFi shield (or the Uno, if 
//  that's easier) and the pin 7 of the LCD using the free space of the 
//  pin bent above it.
//
// This will isolate pin 7 on the LCD, still send the pin 4 signal to the 
// WiFi shield, and reroute the signal from pin 2 on your Arduino to pin 7 
// on the LCD shield.
//

//
// Rerouting pin 4 (optional):
//
//   Bend pin 4 on the LCD shield and the WiFi shield outward so it 
//   doesn't make contact with the header
//
//   Use LiquidCrystal lcd(8,9,3,5,6,2); in your code
//
//   Attach a jumper between the pin 4 on the header of the WiFi shield 
//   and the pin 4 on the Arduino Uno
//
//   Attach a jumper between the pin 3 of the WiFi shield (or the Uno, if 
//   that's easier) and the pin 4 of the LCD using the free space of the 
//   pin bent above it.
//
// This will isolate pin 4 on the LCD, still send the pin 4 signal to 
// the WiFi shield, and reroute the signal from pin 3 on your Arduino 
// to pin 4 on the LCD shield.
//

//#define MONDAY     1
//#define TUESDAY    2
//#define WENDESDAY  3
//#define THURSDAY   4
//#define FRIDAY     5
//#define SATURDAY   6
//#define SUNDAY     7

//static uint8_t state;

#define LCD_ERROR_NONE  0x00
#define LCD_ERROR_TIME  0x01   // Time not set
#define LCD_ERROR_SYNC  0x02   // Time out of sync

static uint8_t error;

// ===================================================================
//   LCD_Print_Weekday
// ===================================================================
static void LCD_Print_Weekday ()
{
  int w = weekday();         // the weekday now (Sunday is day 1) 

  lcd.print(dayStr(w));

#if 0
  switch (day) {
  case MONDAY: lcd.print(F("MON")); break;
  case TUESDAY: lcd.print(F("TUE")); break;
  case WENDESDAY: lcd.print(F("WED")); break;
  case THURSDAY: lcd.print(F("THU")); break;
  case FRIDAY: lcd.print(F("FRI")); break;
  case SATURDAY: lcd.print(F("SAT")); break;
  case SUNDAY: lcd.print(F("SUN")); break;
  }
#endif // 0
  return;
}

// ===================================================================
//   LCD_Print_Time
// ===================================================================
static void LCD_Print_Time ()
{
  int h = hour();
  int m = minute();

  if (h < 10) {
    lcd.print(F("0"));
  }
  lcd.print(h,DEC);

  lcd.print(F(":"));

  if (m < 10) {
    lcd.print(F("0"));
  }
  lcd.print(m,DEC);
}

#if 0
// ===================================================================
//   processSyncMessage
//
//   Synchronize time from time to time
// ===================================================================
void processSyncMessage () 
{
  time_t time = 0;

  setTime(time);   // Sync Arduino clock to the time received
}
#endif

extern "C" {

// ===================================================================
//   LCD_Display_Error
// ===================================================================
void LCD_Display_Error (int8_t err)
{
  lcd.setCursor(0,0);
  lcd.print(F("ERR: Fatal !"));
  lcd.setCursor(0,1);
  lcd.print(F("----------------"));
}

// ===================================================================
//   LCD_Display_Root
// ===================================================================
void LCD_Display_Root (void)
{
  lcd.setCursor(0,0);
  lcd.print(F("N "));

  if (timeStatus() == timeNeedsSync) {
    lcd.print(F("ERR: Time Sync !"));
  }

  else if (error == LCD_ERROR_TIME) {
    lcd.print(F("ERR: Set Time!"));
  }

  else {
    LCD_Print_Weekday();
    lcd.print(F("      "));
    LCD_Print_Time ();
  }

  lcd.setCursor(0,1);
  lcd.print(F("EXT:-"));
  lcd.print(5);
  lcd.print(F("C"));
  lcd.print(F(" INT:"));
  lcd.print(20);
  lcd.print(F("C"));
}

// ===================================================================
//   LCD_Display_Menu
// ===================================================================
void LCD_Display_Menu (void)
{
  lcd.setCursor(0,0);
  lcd.print(F(" N "));
  lcd.print(F(" R "));
  lcd.print(F(" H "));
  lcd.print(F(" M "));
  lcd.print(F(" W "));

  lcd.setCursor(0,1);
  lcd.print(F(" | "));
}

// ===================================================================
//   LCD_setup
// ===================================================================
void LCD_setup (void)
{
  error = LCD_ERROR_NONE;

  //
  // LCD dimentions
  //
  lcd.begin(16,2);
  lcd.clear();      // this clears the LCD. You can use this at any time
  //lcd.print(F("Yes it works!"));

  //
  // Set some default time, so display can work.
  // But mark out-of-sync until sync'd
  //
  setTime(0,0,0,1,1,2014);
  //error = LCD_ERROR_TIME;

#if 0
  //
  // Sync time via ethernet: http://playground.arduino.cc/Code/Time
  //
  Ethernet.begin(mac,ip,gateway);  
  PRINTF ("waiting for sync");
  setSyncProvider(getNtpTime);
  while(timeStatus()== timeNotSet) {
     ; // wait until the time is set by the sync provider
  }
#endif // 0

}

}

